package com.hh.materialCostPrice.service.impl;

import com.hh.legalFactory.mapper.FactoryMapper;
import com.hh.legalFactory.mapper.LegalPersonMapper;
import com.hh.materialCostPrice.Vo.*;
import com.hh.materialCostPrice.bean.SpareCostPrice;
import com.hh.materialCostPrice.mapper.MaterialPriceMapper;
import com.hh.materialCostPrice.service.CostPriceService;
import com.hh.spare.mapper.SpareMapper;
import com.hh.spare.vo.QuerySetSpareVo;
import com.hh.spare.vo.SpareVo;
import com.hh.tax.mapper.TaxMapper;
import com.hh.tax.vo.QueryAllTaxTypeVo;
import com.hh.utils.PageVo;
import com.hh.utils.ResultVo;
import com.hh.utils.SparePriceUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author Hanh
 * @date 2023/8/7 19:55s
 */
@Service
public class CostPriceServiceImpl implements CostPriceService {

    @Resource
    private MaterialPriceMapper materialPriceMapper;
    @Resource
    private TaxMapper taxMapper;
    @Resource
    private SpareMapper spareMapper;
    @Resource
    private FactoryMapper factoryMapper;

    @Resource
    private LegalPersonMapper legalPersonMapper;

    @Override
    public ResultVo queryAllTaxType() {
        List<QueryAllTaxTypeVo> taxTypeVos = taxMapper.getAllTax();
        return taxForWeb(taxTypeVos);
    }

    @Override
    public ResultVo querySparePage(SpareVo spareVo) {
        //计算总条数
        //1.计算总的数据量
        Integer totalNumber = spareMapper.getAllSpare(spareVo);
        //2.计算偏移量
        spareVo.setOffSize((spareVo.getPageIndex()-1)* spareVo.getPageSize());
        //3.获取合适条件的数据
        List<QuerySetSpareVo> spareList = spareMapper.getSpareForWeb(spareVo);
        //4.计算总页数
        PageVo<QuerySetSpareVo> pageVo = new PageVo<>();
        Integer totalPage =totalNumber%spareVo.getPageSize()==0?totalNumber/spareVo.getPageSize():
                totalNumber/spareVo.getPageSize()+1;
        pageVo.setTotalNumber(totalNumber);
        pageVo.setPageIndex(spareVo.getPageIndex());
        pageVo.setDataList(spareList);
        pageVo.setOffSize((spareVo.getPageIndex()- 1)* spareVo.getPageSize());
        pageVo.setTotalPage(totalPage);
        return ResultVo.success(pageVo);
    }

    @Override
    public ResultVo queryMaterialCostPrice(QueryPageVo queryPageVo) {
        //计算总条数
        //1.计算总的数据量
        Integer totalNumber = materialPriceMapper.getAllMaterialCostPriceCount(queryPageVo);
        //2.计算偏移量
        queryPageVo.setOffsize((queryPageVo.getPageIndex()-1)* queryPageVo.getPageSize());
        //3.获取合适条件的数据
        List<QueryPageForFrontVo> sparePriceList = materialPriceMapper.getMatterialCostPrice(queryPageVo);
        //3.1根据获取到的数据进行填充
        for (QueryPageForFrontVo queryPageForFrontVo:sparePriceList){
            //对于价格分类进行名称回显展示
            queryPageForFrontVo.setPriceTypeName(SparePriceUtil.getPriceTypeName(queryPageForFrontVo.getPriceType()));
            //对于状态名称进行回显展示
            queryPageForFrontVo.setStatusName(SparePriceUtil.getStatusName(queryPageForFrontVo.getStatus()));
            //对于货币名称进行回显展示
            queryPageForFrontVo.setCurrencyCodeName(SparePriceUtil.getCurrencyCodeName(queryPageForFrontVo.getCurrencyCode()));
        }
        //4.计算总页数
        PageVo<QueryPageForFrontVo> pageVo = new PageVo<>();
        Integer totalPage =totalNumber%queryPageVo.getPageSize()==0?totalNumber/queryPageVo.getPageSize():
                totalNumber/queryPageVo.getPageSize()+1;
        pageVo.setTotalNumber(totalNumber);
        pageVo.setPageIndex(queryPageVo.getPageIndex());
        pageVo.setDataList(sparePriceList);
        pageVo.setOffSize((queryPageVo.getPageIndex()- 1)* queryPageVo.getPageSize());
        pageVo.setTotalPage(totalPage);
        return ResultVo.success(pageVo);
    }

    @Override
    public ResultVo updateSparePriceStatus(UpdateStatusVo statusVo) {
        materialPriceMapper.updateSparePriceStatus(statusVo);
        return ResultVo.success();
    }

    //检查法人是否合法
    public  Boolean judgeLegalPersonByCode(String legalPersonCode){
        Integer countLegalPerson = legalPersonMapper.getCountByCode(legalPersonCode);
        if (countLegalPerson==0){
            return false;
        }else {
            return true;
        }
    }

    //检查法人工厂是否合法
    public  Boolean judgePlantByLeaglCodeAndPlantCode(String legalPersonCode,String legalPlantCode){
        Integer countFactory = factoryMapper.getPlanByLegalCodeAndPlantCode(legalPersonCode,legalPlantCode);
        if (countFactory==0){
            return false;
        }else {
            return true;
        }
    }

    //检查含税类型是否合法
    public  Boolean judgeTaxById(Integer taxType){
        Integer countTax = taxMapper.getTaxById(taxType);
        if (countTax==0){
            return false;
        }else {
            return true;
        }
    }

    //检查备件是否合法
    public  Boolean judgeSpareByCode(String materialCode){
        Integer countSpare = spareMapper.judgeAddSpareCodeIsExist(materialCode);
        if (countSpare==0){
            return false;
        }else {
            return true;
        }
    }

    //根据新增起止时间与原有数据获取合适的时间片段        --时间筛选算法
    public static List<SpareCostPrice> getRightSparePrice(List<SpareCostPrice> costPrices,Date start,Date end){
        List<SpareCostPrice> rightList =new ArrayList<>();
        Integer flag = 0; //用来记录包含的原有数据的数据量，如果存在，旧直接对其进行覆盖
          //用来记录List的下标
        for (int i = 0; i < costPrices.size(); i++) {
            //如果开始时间在原有数据结束日期之后  或者 结束时间在原有数据的开始日期之前
            SpareCostPrice spareCostPrice = costPrices.get(i);
            if (start.after(spareCostPrice.getEndtime())||end.before(spareCostPrice.getStarttime())){

            }else if (start.compareTo(spareCostPrice.getStarttime())>0&&start.before(spareCostPrice.getEndtime())){
                //在原有时间段中包含新增开始时间的数据
                rightList.add(spareCostPrice);
            }else if (end.after(spareCostPrice.getStarttime())&&end.compareTo(spareCostPrice.getEndtime())<0) {
                //在原有时间段中包含结束时间的数据
                rightList.add(spareCostPrice);
            }else if (start.compareTo(spareCostPrice.getStarttime())==0&&end.compareTo(spareCostPrice.getEndtime())==0) {
                //如果起止时间都一样的数据  这个数据只有一个
                rightList.add(spareCostPrice);
            } else if (start.before(spareCostPrice.getStarttime())&&end.after(spareCostPrice.getEndtime())) {
                //如果新增的时间段内包含该时间段
                if (flag==0){   //遇到第一个包含的数据段
                    if (rightList.size()==0){ //如果在此之前没有合适的字段，就可以把该时间段的值进行修改  起始时间改为新增开始时间，结束时间不变
                        spareCostPrice.setStarttime(start);
                        rightList.add(spareCostPrice);
                        flag=rightList.size();    //flag记录了当前数据的存放下下标+1
                    }else { //如果该数据段不是第一个数据段，  就可以把该数据段的起始日期改为前一个日期的结束后一天
                        spareCostPrice.setStarttime(SparePriceUtil.getNextDay(rightList.get(rightList.size()-1).getEndtime()));
                        rightList.add(spareCostPrice);
                        flag=rightList.size();    //flag记录了当前数据的存放下标+1
                    }
                }else {          //遇到其他的包含的时间数据段
                    //修改第一个包含的数据段的结束日期到现在的结束日期
                    rightList.get(flag-1).setEndtime(spareCostPrice.getEndtime());
                }
            }
        }
        if (flag<=rightList.size()&&flag>0){//如果最后一个存放的数据已经是被包含
            if (rightList.size()==1&&flag==1){ //表明如果只有一个包含的数据情况下  起始数据已经被改为起始日期，把原数据的结束日期改为新增的结束日期即可
                rightList.get(0).setEndtime(end);
            } else if (flag==1) { //表明包含情况下的数据是第一个的话，将第一个的日期的开始改为新增日期的开始(已做)，结束改为下一个日期的开始前一天
                rightList.get(0).setEndtime(SparePriceUtil.getNextDay(rightList.get(1).getStarttime()));
            } else if (flag==rightList.size()) {  //表明如果该数据段最后一个的情况下   把该数据的起始日期改为上一个日期的结束日期的下一天到新增的结束日期
                //该数据日期改为上个原有数据的结束日期前一天(已做)
                rightList.get(flag-1).setStarttime(SparePriceUtil.getNextDay(rightList.get(flag-2).getEndtime()));
                //该数据的结束日期为新增结束日期
                rightList.get(flag-1).setEndtime(end);
            } else {  //该数据段前后都有数据的情况下   把该数据段的起止日期改为前一个的结束日期的后一天（已做）  到  下个日期的开始日期的前一天
                rightList.get(flag-1).setEndtime(SparePriceUtil.getPreviousDay(rightList.get(flag).getStarttime()));
            }
        }
        return rightList;
    }

    //检验是否可以正确插入  必须是开始时间小于结束时间才执行
    public static Boolean trueAddSparePrice(Date start,Date end){
        if (start.compareTo(end)<0){
            return true;
        }else {
            return false;
        }
    }


    //把AddSparePriceVo转化为SpareCostPrice方便统一算法
    public SpareCostPrice convertAddVoToSparePrice(AddSparePriceVo addSparePriceVo){
        SpareCostPrice spareCostPrice = new SpareCostPrice();
        spareCostPrice.setCurrencyCode(addSparePriceVo.getCurrencyCode());
        spareCostPrice.setEndtime(addSparePriceVo.getEnd());
        spareCostPrice.setStarttime(addSparePriceVo.getStart());
        spareCostPrice.setPriceType(addSparePriceVo.getPriceType());
        spareCostPrice.setPrice(addSparePriceVo.getPrice());
        Integer legalpersonId =  legalPersonMapper.getLegalPersonIdByCode(addSparePriceVo.getLegalPersonCode());
        spareCostPrice.setLegalpersonId(legalpersonId);
        spareCostPrice.setRemark(addSparePriceVo.getRemark());
        spareCostPrice.setPrice(addSparePriceVo.getPrice());
        spareCostPrice.setTaxId(addSparePriceVo.getTaxType());
        Integer factoryId =  factoryMapper.getPlantIdByPlantCode(addSparePriceVo.getLegalPlantCode());
        spareCostPrice.setFactoryId(factoryId);
        Integer spareId = spareMapper.getSpareIdByCode(addSparePriceVo.getMaterialCode());
        spareCostPrice.setMaterialId(spareId);
        return spareCostPrice;
    }

    /**
     * 插入算法
     * @param pricesList  筛选好后需要操作的备件价格List
     * @param spareCostPrice  需要插入的备件价格实体
     * @return
     */
    @Transactional
    public ResultVo insertSparePrice( List<SpareCostPrice> pricesList,SpareCostPrice spareCostPrice){
        try {
            Date startTime =spareCostPrice.getStarttime();  //做一个新增时间的开始指代
            Date endTime =spareCostPrice.getEndtime();      //做一个新增时间的结束指代
            if (pricesList.size()==0){
                //如果没有合适数据的情况下
                //直接执行插入
                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                return ResultVo.success();
            }else {
                //筛选到需要修改的数据后
                if (pricesList.size()==1){//如果只有一个数据的情况下
                    if (startTime.before(pricesList.get(0).getStarttime())){ //如果新增的开始日期在合适数据的日期之前
                        if (endTime.before(pricesList.get(0).getEndtime())){ //如果新增的结束日期在合适数据的结束日期之前
                            //修改原有数据的开始日期为新增日期的结束日期的后一天  执行插入, 然后插入新增数据
                            pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                            //插入原有数据
                            if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                            }
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        } else if (endTime.compareTo(pricesList.get(0).getEndtime())==0 ||endTime.after(pricesList.get(0).getEndtime())) {  //结束日期相等或大于原结束日期的情况
                            //原有数据直接被覆盖，插入新增即可
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        }
                    } else if (startTime.compareTo(pricesList.get(0).getStarttime())==0) { //如果新增开始日期与原有开始日期相等
                        if (endTime.before(pricesList.get(0).getEndtime())){  //如果结束日期在原有日期的结束之前
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            //把原有的数据的开始日期改为新增日期结束的后一天再插入
                            pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                            //执行插入原有数据
                            //插入原有数据
                            if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                            }
                        } else if (endTime.compareTo(pricesList.get(0).getEndtime())>=0) {  //如果开始和结束时间一致或超过
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        }
                    }else { //如果新增开始日期比原有的开始日期晚
                        if (endTime.compareTo(pricesList.get(0).getEndtime())<0){//结束日期比原有结束日期早
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            //将原有数据拆分两段，第一段的开始日期不变，结束日期改为新增开始的后一天， 第二段结束日期不变，开始日期变为新增结束的后一天
                            SpareCostPrice sparePriceFirst = pricesList.get(0);
                            SpareCostPrice sparePriceSecond = pricesList.get(0);
                            sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                            //插入
                            //插入原有数据
                            if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                            }
                            sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                            //插入
                            if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                            }
                        } else  { //结束日期比原有结束日期相等或晚一点
                            //把原有日期的结束时间调整为新增的前一天再插入
                            pricesList.get(0).setEndtime(SparePriceUtil.getPreviousDay(startTime));
                            //插入
                            if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                            }
                            //把新增数据进行插入
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        }

                    }
                } else if (pricesList.size()==2) {//只有三种情况  1:该时间段包含了新增的开始时间 + 一个可以覆盖的中间时间  2. 一个可以覆盖的中间时间 +该时间段包含了新增的结束时间 3.两个时间段一个包含新增，一个包含结束
                    if(startTime.compareTo(pricesList.get(0).getStarttime())>=0&&startTime.compareTo(pricesList.get(0).getEndtime())<0){ //如果第一个时间段包含了新增开始时间
                        if (endTime.compareTo(pricesList.get(1).getStarttime())>0&&startTime.compareTo(pricesList.get(1).getEndtime())<=0){ //第二个时间段包含了结束的时间
                            //新增数据可以直接进行插入
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            SpareCostPrice sparePriceFirst = pricesList.get(0);
                            SpareCostPrice sparePriceSecond = pricesList.get(1);
                            //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                            sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                            //执行插入
                            if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                            }
                            //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                            sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                            //执行插入
                            if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                            }
                        } else  {  //第二个时间段   是一个可以覆盖的中间时间段
                            //新增数据可以直接进行插入
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            //原有时间进行插入时把结束日期改为新增日期的前一天
                            SpareCostPrice sparePriceFirst = pricesList.get(0);
                            sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                            //执行插入
                            if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                            }
                        }
                    }else {   //一个可以覆盖的中间时间 +该时间段包含了新增的结束时间
                        //新增数据可以直接进行插入
                        //插入新增数据
                        materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        SpareCostPrice sparePriceSecond = pricesList.get(1);
                        //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                        sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                        //执行插入
                        if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                            materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                        }
                    }
                }else {  //包含一个含有开始时间段的数据，一个中间时间段，一个结束时间段的数据
                    //原有数据可以直接插入
                    //插入新增数据
                    materialPriceMapper.insertExistSparePrice(spareCostPrice);
                    SpareCostPrice sparePriceFirst = pricesList.get(0);
                    //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                    sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                    //执行插入
                    if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                        materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                    }
                    SpareCostPrice sparePriceSecond = pricesList.get(2);
                    //修改最后一个时间段的开始时间为新增日期的结束的后一天进行插入
                    sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                    materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResultVo.error("插入失败");
        }


        return ResultVo.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo addSparePrice(AddSparePriceVo addSparePriceVo) throws ParseException {
        //检查法人合法
        if (!judgeLegalPersonByCode(addSparePriceVo.getLegalPersonCode())){
            return ResultVo.error("您所选择的法人已禁用或不存在！");
        }
        //检查工厂合法
        if (!judgePlantByLeaglCodeAndPlantCode(addSparePriceVo.getLegalPersonCode(),addSparePriceVo.getLegalPlantCode())){
            return ResultVo.error("您所选择的工厂或已销毁，请重新选择！");
        }
        //检查含税类型合法
        if (!judgeTaxById(addSparePriceVo.getTaxType())){
            return ResultVo.error("您搜选择的税码已不存在，请重新选择！");
        }
        //检验备件是否合法
        if (!judgeSpareByCode(addSparePriceVo.getMaterialCode())){
            return ResultVo.error("您搜选择的备件编码已禁用或不存在，请重新选择！");
        }

        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
        Date startTime =sdf.parse(addSparePriceVo.getStartTime());
        Date endTime =sdf.parse(addSparePriceVo.getEndTime());
        addSparePriceVo.setStart(startTime);
        addSparePriceVo.setEnd(endTime);
        //检查输入日期是否合法
        if (!trueAddSparePrice(startTime,endTime)){
            return ResultVo.error("您输入的结束日期无效，请重试！");
        }
        //获取当前时间的时间戳
        long testFast1 = System.currentTimeMillis();
        try {
            //根据备件code与法人legal_person与货币类型检查备件成本价是否已经存在
            List<SpareCostPrice> sparePriceList = materialPriceMapper.countExistSparePriceByCode(addSparePriceVo);
            if (sparePriceList.size()==0){
                //在法人或者备件都不相同的情况下 直接进行插入
                materialPriceMapper.addSparePrice(addSparePriceVo);
                return ResultVo.success();
            }else {
                //在同法人 同备件 同样计算成本的情况下
                //筛选合适的时间段
                List<SpareCostPrice> pricesList = getRightSparePrice(sparePriceList,addSparePriceVo.getStart(),addSparePriceVo.getEnd());
                if (pricesList.size()==0){
                    //如果没有合适数据的情况下
                    //直接执行插入
                    materialPriceMapper.addSparePrice(addSparePriceVo);
                    return ResultVo.success();
                }else {
                    //筛选到需要修改的数据后
                    //删除原有数据中  包含新增日期的时间段、包含结束日期的时间段、被新增结束日期包含的时间段
                    materialPriceMapper.removeSparePrice(addSparePriceVo);
                    if (pricesList.size()==1){//如果只有一个数据的情况下
                        if (startTime.before(pricesList.get(0).getStarttime())){ //如果新增的开始日期在合适数据的日期之前
                            if (endTime.before(pricesList.get(0).getEndtime())){ //如果新增的结束日期在合适数据的结束日期之前
                                //修改原有数据的开始日期为新增日期的结束日期的后一天  执行插入, 然后插入新增数据
                                pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                                //插入原有数据
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                            } else if (endTime.compareTo(pricesList.get(0).getEndtime())==0 ||endTime.after(pricesList.get(0).getEndtime())) {  //结束日期相等或大于原结束日期的情况
                                //原有数据直接被覆盖，插入新增即可
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                            }
                        } else if (startTime.compareTo(pricesList.get(0).getStarttime())==0) { //如果新增开始日期与原有开始日期相等
                            if (endTime.before(pricesList.get(0).getEndtime())){  //如果结束日期在原有日期的结束之前
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                                //把原有的数据的开始日期改为新增日期结束的后一天再插入
                                pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                                //执行插入原有数据
                                //插入原有数据
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                            } else if (endTime.compareTo(pricesList.get(0).getEndtime())>=0) {  //如果开始和结束时间一致或超过
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                            }
                        }else { //如果新增开始日期比原有的开始日期晚
                            if (endTime.compareTo(pricesList.get(0).getEndtime())<0){//结束日期比原有结束日期早
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                                //将原有数据拆分两段，第一段的开始日期不变，结束日期改为新增开始的后一天， 第二段结束日期不变，开始日期变为新增结束的后一天
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                SpareCostPrice sparePriceSecond = pricesList.get(0);
                                //存放原有的结束值
                                Date secondEnd =  new Date(sparePriceFirst.getEndtime().getTime());

                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //插入
                                //插入原有数据
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                                sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                                sparePriceSecond.setEndtime(secondEnd);
                                //插入
                                if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                                }
                            } else  { //结束日期比原有结束日期相等或晚一点
                                //把原有日期的结束时间调整为新增的前一天再插入
                                pricesList.get(0).setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //插入
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                                //把新增数据进行插入
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                            }

                        }
                    } else if (pricesList.size()==2) {//只有三种情况  1:该时间段包含了新增的开始时间 + 一个可以覆盖的中间时间  2. 一个可以覆盖的中间时间 +该时间段包含了新增的结束时间 3.两个时间段一个包含新增，一个包含结束
                        if(startTime.compareTo(pricesList.get(0).getStarttime())>=0&&startTime.compareTo(pricesList.get(0).getEndtime())<0){ //如果第一个时间段包含了新增开始时间
                            if (endTime.compareTo(pricesList.get(1).getStarttime())>0&&startTime.compareTo(pricesList.get(1).getEndtime())<=0){ //第二个时间段包含了结束的时间
                                //新增数据可以直接进行插入
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                SpareCostPrice sparePriceSecond = pricesList.get(1);
                                //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //执行插入
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                                //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                                sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                                //执行插入
                                if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                                }
                            } else  {  //第二个时间段   是一个可以覆盖的中间时间段
                                //新增数据可以直接进行插入
                                //插入新增数据
                                materialPriceMapper.addSparePrice(addSparePriceVo);
                                //原有时间进行插入时把结束日期改为新增日期的前一天
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //执行插入
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                            }
                        }else {   //一个可以覆盖的中间时间 +该时间段包含了新增的结束时间
                            //新增数据可以直接进行插入
                            //插入新增数据
                            materialPriceMapper.addSparePrice(addSparePriceVo);
                            SpareCostPrice sparePriceSecond = pricesList.get(1);
                            //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                            sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                            //执行插入
                            if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                            }
                        }
                    }else {  //包含一个含有开始时间段的数据，一个中间时间段，一个结束时间段的数据
                        //原有数据可以直接插入
                        //插入新增数据
                        materialPriceMapper.addSparePrice(addSparePriceVo);
                        SpareCostPrice sparePriceFirst = pricesList.get(0);
                        //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                        sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                        //执行插入
                        if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                            materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                        }
                        SpareCostPrice sparePriceSecond = pricesList.get(2);
                        //修改最后一个时间段的开始时间为新增日期的结束的后一天进行插入
                        sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                        materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                    }
                }
                //获取当前时间的时间戳
                long testFast2 = System.currentTimeMillis();
                long result = testFast2-testFast1;
                System.out.println(result);
                return ResultVo.success();
            }

        }catch (Exception e){
            e.printStackTrace();
            return ResultVo.error("插入失败");
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo updateSparePrice(ModifySparePriceVo modifyVo) {
        try{
            SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
            Date endTime = sdf.parse(modifyVo.getEndTime());

            // 根据id拿到原有的数据
            SpareCostPrice spareCostPrice = materialPriceMapper.getMatterialCostPriceById(modifyVo);
            //判断日期有无变化，若无变化就根据id修改对应的remark与price就可以
            if (spareCostPrice.getEndtime().compareTo(endTime)==0){
                //根据id修改其数据即可
                materialPriceMapper.modifyDataById(spareCostPrice.getId(),modifyVo.getPrice(),modifyVo.getRemark());
                return ResultVo.success();
            }

            // 根据modify修改拿到的原始数据执行插入
            spareCostPrice.setEndtime(endTime);
            spareCostPrice.setPrice(modifyVo.getPrice());
            spareCostPrice.setRemark(modifyVo.getRemark());
            //2 拿原数据中的开始时间与修改结束时间做校验
            if (!trueAddSparePrice(spareCostPrice.getStarttime(),endTime)){
                return ResultVo.error("您输入的结束日期有误！应输入的日期大于开始日期！");
            }

            //简单做一个开始时间的指代
            Date startTime =spareCostPrice.getStarttime();
          /*  //3.1删除原数据
            materialPriceMapper.removeSparePriceById(spareCostPrice.getId());*/
            //3.1 获取原有数据中与该数据相关的数据
            List<SpareCostPrice> sparePriceList = materialPriceMapper.countExistSparePriceById(spareCostPrice);
            if (sparePriceList.size()==0){//如果只有原数据的情况下  直接进行插入
                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                return ResultVo.success();
            }else {
                //筛选到需要修改的数据后
                //删除原有数据中  包含新增日期的时间段、包含结束日期的时间段、被新增结束日期包含的时间段
                materialPriceMapper.removeSparePriceByUp(spareCostPrice);
                //筛选合适的时间段
                List<SpareCostPrice> pricesList = getRightSparePrice(sparePriceList,startTime,endTime);
                if (pricesList.size()==0){
                    //如果没有合适数据的情况下
                    //直接执行插入
                    materialPriceMapper.insertExistSparePrice(spareCostPrice);
                    return ResultVo.success();
                }else {
                    //筛选到需要修改的数据后
                    if (pricesList.size()==1){//如果只有一个数据的情况下
                        if (startTime.before(pricesList.get(0).getStarttime())){ //如果新增的开始日期在合适数据的日期之前
                            if (endTime.before(pricesList.get(0).getEndtime())){ //如果新增的结束日期在合适数据的结束日期之前
                                //修改原有数据的开始日期为新增日期的结束日期的后一天  执行插入, 然后插入新增数据
                                pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                                //插入原有数据
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            } else if (endTime.compareTo(pricesList.get(0).getEndtime())==0 ||endTime.after(pricesList.get(0).getEndtime())) {  //结束日期相等或大于原结束日期的情况
                                //原有数据直接被覆盖，插入新增即可
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            }
                        } else if (startTime.compareTo(pricesList.get(0).getStarttime())==0) { //如果新增开始日期与原有开始日期相等
                            if (endTime.before(pricesList.get(0).getEndtime())){  //如果结束日期在原有日期的结束之前
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                                //把原有的数据的开始日期改为新增日期结束的后一天再插入
                                pricesList.get(0).setStarttime(SparePriceUtil.getNextDay(endTime));
                                //执行插入原有数据
                                //插入原有数据
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                            } else if (endTime.compareTo(pricesList.get(0).getEndtime())>=0) {  //如果开始和结束时间一致或超过
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            }
                        }else { //如果新增开始日期比原有的开始日期晚
                            if (endTime.compareTo(pricesList.get(0).getEndtime())<0){//结束日期比原有结束日期早
                                //记录下原有数据的结束时间，以免被修改
                                Date secondEnd = new Date(pricesList.get(0).getEndtime().getTime());
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                                //将原有数据拆分两段，第一段的开始日期不变，结束日期改为新增开始的后一天， 第二段结束日期不变，开始日期变为新增结束的后一天
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                SpareCostPrice sparePriceSecond = pricesList.get(0);
                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //插入
                                //插入原有数据
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                                sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                                sparePriceSecond.setEndtime(secondEnd);
                                //插入
                                if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                                }
                            } else  { //结束日期比原有结束日期相等或晚一点
                                //把原有日期的结束时间调整为新增的前一天再插入
                                pricesList.get(0).setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //插入
                                if (trueAddSparePrice(pricesList.get(0).getStarttime(),pricesList.get(0).getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(pricesList.get(0));
                                }
                                //把新增数据进行插入
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            }

                        }
                    } else if (pricesList.size()==2) {//只有三种情况  1:该时间段包含了新增的开始时间 + 一个可以覆盖的中间时间  2. 一个可以覆盖的中间时间 +该时间段包含了新增的结束时间 3.两个时间段一个包含新增，一个包含结束
                        if(startTime.compareTo(pricesList.get(0).getStarttime())>=0&&startTime.compareTo(pricesList.get(0).getEndtime())<0){ //如果第一个时间段包含了新增开始时间
                            if (endTime.compareTo(pricesList.get(1).getStarttime())>0&&startTime.compareTo(pricesList.get(1).getEndtime())<=0){ //第二个时间段包含了结束的时间
                                //新增数据可以直接进行插入
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                SpareCostPrice sparePriceSecond = pricesList.get(1);
                                //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //执行插入
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                                //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                                sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                                //执行插入
                                if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                                }
                            } else  {  //第二个时间段   是一个可以覆盖的中间时间段
                                //新增数据可以直接进行插入
                                //插入新增数据
                                materialPriceMapper.insertExistSparePrice(spareCostPrice);
                                //原有时间进行插入时把结束日期改为新增日期的前一天
                                SpareCostPrice sparePriceFirst = pricesList.get(0);
                                sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                                //执行插入
                                if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                                    materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                                }
                            }
                        }else {   //一个可以覆盖的中间时间 +该时间段包含了新增的结束时间
                            //新增数据可以直接进行插入
                            //插入新增数据
                            materialPriceMapper.insertExistSparePrice(spareCostPrice);
                            SpareCostPrice sparePriceSecond = pricesList.get(1);
                            //修改第二个时间段的开始时间为新增日期的结束前一天执行插入
                            sparePriceSecond.setStarttime((SparePriceUtil.getNextDay(endTime)));
                            //执行插入
                            if (trueAddSparePrice(sparePriceSecond.getStarttime(),sparePriceSecond.getEndtime())){
                                materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                            }
                        }
                    }else {  //包含一个含有开始时间段的数据，一个中间时间段，一个结束时间段的数据
                        //原有数据可以直接插入
                        //插入新增数据
                        materialPriceMapper.insertExistSparePrice(spareCostPrice);
                        SpareCostPrice sparePriceFirst = pricesList.get(0);
                        //修改第一个时间段的结束时间为新增日期的开始前一天执行插入
                        sparePriceFirst.setEndtime(SparePriceUtil.getPreviousDay(startTime));
                        //执行插入
                        if (trueAddSparePrice(sparePriceFirst.getStarttime(),sparePriceFirst.getEndtime())){
                            materialPriceMapper.insertExistSparePrice(sparePriceFirst);
                        }
                        SpareCostPrice sparePriceSecond = pricesList.get(2);
                        //修改最后一个时间段的开始时间为新增日期的结束的后一天进行插入
                        sparePriceSecond.setStarttime(SparePriceUtil.getNextDay(endTime));
                        materialPriceMapper.insertExistSparePrice(sparePriceSecond);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResultVo.error("插入失败");
        }
        return ResultVo.success();
    }


    public static ResultVo taxForWeb(List<QueryAllTaxTypeVo> taxTypeVos){
        //做一个简单拼接
        for (QueryAllTaxTypeVo taxTypeVo:taxTypeVos) {
            taxTypeVo.setTaxDec(taxTypeVo.getTaxDec()+" "+taxTypeVo.getTax()+"%");
        }
        return ResultVo.success(taxTypeVos);
    }
}
